import { ComponentClass } from 'react'
import Taro, { Component, Config } from '@tarojs/taro'
import { View, Button, Image, Text } from '@tarojs/components'
import { connect } from '@tarojs/redux'
import logo from '../../static/images/logo@2x.png'
import loginTips from '../../static/images/login_tips@2x.png'
import wxLoginImage from '../../static/images/wx_login@2x.png'
import { fetch } from '../../utils/fetch'
// import { setToken } from '../../actions/token'
import { inject, observer } from '@tarojs/mobx'

import './index.less'

// #region 书写注意
//
// 目前 typescript 版本还无法在装饰器模式下将 Props 注入到 Taro.Component 中的 props 属性
// 需要显示声明 connect 的参数类型并通过 interface 的方式指定 Taro.Component 子类的 props
// 这样才能完成类型检查和 IDE 的自动提示
// 使用函数模式则无此限制
// ref: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/20796
//
// #endregion

type PageOwnProps = {
  tokenStore: {
    setToken: Function
  }
}

type PageState = {}

// type PageDispatchProps = {
//   saveToken: (token) => void
// }

type IProps = PageOwnProps

interface Index {
  props: IProps
}

// @connect(
//   () => ({}),
//   dispatch => ({
//     saveToken(token) {
//       dispatch(setToken(token))
//     }
//   })
// )
@inject('tokenStore')
@observer
class Index extends Component {
  /**
   * 指定config的类型声明为: Taro.Config
   *
   * 由于 typescript 对于 object 类型推导只能推出 Key 的基本类型
   * 对于像 navigationBarTextStyle: 'black' 这样的推导出的类型是 string
   * 提示和声明 navigationBarTextStyle: 'black' | 'white' 类型冲突, 需要显示声明类型
   */
  config: Config = {
    navigationBarTitleText: ''
  }

  // 微信授权登录
  wxLogin = e => {
    const { errMsg } = e.detail
    if (errMsg === 'getUserInfo:fail auth deny') return

    const { avatarUrl: avatar, nickName: nickname } = e.detail.userInfo

    Taro.login({
      success: async ({ code }) => {
        const result: any = await fetch({
          url: 'user/wxlogin',
          method: 'POST',
          data: {
            code,
            nickname,
            avatar
          }
        })

        if (result.data.status === 0) {
          // 保存到本地及store中
          Taro.setStorageSync('my_token', result.data.token)
          // this.props.saveToken(result.data.token)
          this.props.tokenStore.setToken(result.data.token)

          Taro.showToast({
            title: result.data.message,
            icon: 'success',
            duration: 500
          }).then(() => {
            setTimeout(() => {
              // 跳转
              Taro.reLaunch({
                url: '/pages/home/index'
              })
            }, 500)
          })
        }
      }
    })
  }

  // 跳转到手机号登录页面
  phoneLogin(){
    Taro.navigateTo({
      url: '/pages/phone-login/index'
    })
  }

  render() {
    return (
      <View className="login-container">
        <Image className="logo" src={logo} />
        <Text className="title">蘑菇在线</Text>
        <Image className="login-tips" src={loginTips} />
        <Button
          open-type="getUserInfo"
          onGetUserInfo={this.wxLogin}
          plain
          className="wx-login-button"
        >
          <Image className="wx-login-img" src={wxLoginImage} />
        </Button>
        <Text onClick={this.phoneLogin} className="phone-login">手机号登录</Text>
        <Text className="bottom-tip">Copyright © 2019 蘑菇在线</Text>
      </View>
    )
  }
}

// #region 导出注意
//
// 经过上面的声明后需要将导出的 Taro.Component 子类修改为子类本身的 props 属性
// 这样在使用这个子类时 Ts 才不会提示缺少 JSX 类型参数错误
//
// #endregion

export default Index as ComponentClass<PageOwnProps, PageState>
